package com.printf.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.util.Log;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class ImageUtil {

    /**
     * 保存图片的方法
     */
    public static String saveBitmap(Bitmap bitmap, String saveName, String saveRootPath) {

        File f = new File(saveRootPath, saveName);
        if (f.exists()) {
            f.delete();
        }
        try {
            FileOutputStream out = new FileOutputStream(f);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            out.flush();
            out.close();
            Log.i("TAG", "已经保存");
            return f.getAbsolutePath();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 处理图片的大小
     *
     * @param bitmap
     * @param newBitmapW
     * @param newBitmapH
     * @return
     */
    public static Bitmap handleBitmap(Bitmap bitmap, float newBitmapW, float newBitmapH, int rotate) {

        int height = bitmap.getHeight();
        int width = bitmap.getWidth();

        // 计算缩放比例
        float scaleWidth = ((float) newBitmapW) / width;
        float scaleHeight = ((float) newBitmapH) / height;

        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        //先旋转，后缩小
        if (rotate % 360 != 0) {
            matrix.setRotate(rotate, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
        }

        matrix.postScale(scaleWidth, scaleHeight);
        bitmap = Bitmap.createBitmap(bitmap, 0, 0,
                bitmap.getWidth(), bitmap.getHeight(), matrix, true);

        return bitmap;
    }

//    /**
//     * 颜色缩减的方法
//     */
//    private Bitmap colorReduce(Bitmap img){
//
//        int width = img.getWidth();//获取位图的宽  
//        int height = img.getHeight();//获取位图的高  
//
//        int[] pixels = new int[width * height]; //通过位图的大小创建像素点数组  
//
//        img.getPixels(pixels, 0, width, 0, 0, width, height);
//        int[] gray = new int[height * width];
//
//        for (int i = 0; i < height; i++){
//            for(int j = 0; j < width; j++){
//                int grey = pixels[width * i + j];
//                int red = ((grey & 0x00FF0000) >> 16) / 2;
//                int green = ((grey & 0x0000FF00) >> 8) / 2;
//                int blue = (grey & 0x000000FF) / 2;
//            }
//        }
//
//    }

    /**
     * Sierra 抖动
     * http://caca.zoy.org/study/part3.html
     */
    public static Bitmap convertGreyImgSierra(Bitmap img) {
        int width = img.getWidth();//获取位图的宽  
        int height = img.getHeight();//获取位图的高  

        int[] pixels = new int[width * height]; //通过位图的大小创建像素点数组  

        img.getPixels(pixels, 0, width, 0, 0, width, height);
        int[] gray = new int[height * width];
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int grey = pixels[width * i + j];
                int red = ((grey & 0x00FF0000) >> 16);
                int green = ((grey & 0x0000FF00) >> 8);
                int blue = (grey & 0x000000FF);
                gray[width * i + j] = (int) (0.29900 * red + 0.58700 * green + 0.11400 * blue); // 灰度转化公式;
            }
        }

        int e = 0;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int g = gray[width * i + j];
                if (g > 127) {
                    pixels[width * i + j] = 0xffffffff;
                    e = g - 255;
                } else {
                    pixels[width * i + j] = 0xff000000;
                    e = g;
                }


                if (i < height - 2 && j > 1 && j < width - 2) {
                    //右 1 与 右 2
                    gray[width * i + j + 1] += e * 5 / 32;
                    gray[width * i + j + 2] += e * 3 / 32;

                    // 下 1 左 2 ，下 1 左 1， 下 1 ，下 右 1，下 右 2
                    gray[width + (i + 1) + j - 2] += e / 16;
                    gray[width + (i + 1) + j - 1] += e / 8;
                    gray[width + (i + 1) + j] += e * 5 / 32;
                    gray[width + (i + 1) + j + 1] += e / 8;
                    gray[width + (i + 1) + j + 2] += e / 16;

                    //下 2 左 1，下 2 ，下 2 右 1
                    gray[width + (i + 2) + j - 1] += e / 16;
                    gray[width + (i + 2) + j] += e * 3 / 32;
                    gray[width + (i + 2) + j + 1] += e / 16;
                }
            }
        }
        Bitmap mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        mBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        return mBitmap;
    }

    /**
     * Atkinson 抖动
     * http://caca.zoy.org/study/part3.html
     */
    public static Bitmap convertGreyImgAtkinson(Bitmap img) {

        int width = img.getWidth();//获取位图的宽  
        int height = img.getHeight();//获取位图的高  

        int[] pixels = new int[width * height]; //通过位图的大小创建像素点数组  

        img.getPixels(pixels, 0, width, 0, 0, width, height);
        int[] gray = new int[height * width];
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int grey = pixels[width * i + j];
                int red = (int) (((grey & 0x00FF0000) >> 16));
                int green = (int) (((grey & 0x0000FF00) >> 8));
                int blue = (int) ((grey & 0x000000FF));
                gray[width * i + j] = (int) (0.29900 * red + 0.58700 * green + 0.11400 * blue); // 灰度转化公式;
            }
        }

        int e = 0;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int g = gray[width * i + j];
                if (g > 127) {
                    pixels[width * i + j] = 0xffffffff;
                    e = g - 255;
                } else {
                    pixels[width * i + j] = 0xff000000;
                    e = g;
                }

                int tempE = e / 8;

                if (i < height - 2 && j > 0 && j < width - 2) {
                    //右 1 与 右 2
                    gray[width * i + j + 1] += tempE;
                    gray[width * i + j + 2] += tempE;
                    //下 左 1 下 1 下 右 1
                    gray[width * (i + 1) + j - 1] += tempE;
                    gray[width * (i + 1) + j] += tempE;
                    gray[width * (i + 1) + j + 1] += tempE;
                    //下 2
                    gray[width * (i + 2) + j] += tempE;

//                    judgePoint(gray,i,j+1,width);
//                    judgePoint(gray,i,j+2,width);
//                    judgePoint(gray,i + 1,j-1,width);
//                    judgePoint(gray,i + 1,j,width);
//                    judgePoint(gray,i + 1,j+1,width);
//                    judgePoint(gray,i + 2,j,width);

//                    gray[width * i + j + 1] += tempE;
//                    gray[width * i + j + 2] += tempE;
//                    //下 左 1 下 1 下 右 1
//                    gray[width * (i + 1) + j - 1] += tempE;
//                    gray[width * (i + 1) + j] += tempE;
//                    gray[width * (i + 1) + j + 1] += tempE;
//                    //下 2
//                    gray[width * (i + 2) + j] += tempE;


                }
            }
        }
        Bitmap mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        mBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        return mBitmap;

    }

    /**
     * 网址：https://blog.csdn.net/szfhy/article/details/50644707
     */
    public static Bitmap convertGreyImgDither(Bitmap img) {


        int width = img.getWidth();//获取位图的宽  
        int height = img.getHeight();//获取位图的高  

        int[] pixels = new int[width * height]; //通过位图的大小创建像素点数组  

        img.getPixels(pixels, 0, width, 0, 0, width, height);
        int[] gray = new int[height * width];
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int grey = pixels[width * i + j];
                int red = ((grey & 0x00FF0000) >> 16);
                int green = ((grey & 0x0000FF00) >> 8);
                int blue = (grey & 0x000000FF);
                gray[width * i + j] = (int) (0.29900 * red + 0.58700 * green + 0.11400 * blue); // 灰度转化公式;
            }
        }

        int e = 0;
        for (int i = 0; i < height - 1; i++) {
            for (int j = 0; j < width - 1; j++) {
                int g = gray[width * i + j];
                if (g > 96) {
                    pixels[width * i + j] = 0xffffffff;
                    e = g - 255;
                    gray[width * i + j + 1] += e;
                    if (gray[width * i + j + 1] > 255) {
                        gray[width * i + j + 1] = 255;
                    } else if (gray[width * i + j + 1] < 0) {
                        gray[width * i + j + 1] = 0;
                    }
                } else {
                    pixels[width * i + j] = 0xff000000;
                    e = g;
                    gray[width * i + j + 1] += e;
                    if (gray[width * i + j + 1] > 255) {
                        gray[width * i + j + 1] = 255;
                    } else if (gray[width * i + j + 1] < 0) {
                        gray[width * i + j + 1] = 0;
                    }
                }

            }
        }
        Bitmap mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        mBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        return mBitmap;


    }

//    /**
//     * 处理半色调图片
//     * @param img
//     * @return
//     */
//    public static Bitmap convertGreyImgByFloyd(Bitmap img, Context context,boolean isJudge) {
//
//        int bitmapTowValuedType = ParameterUtil.getBitmapTowValuedType(context);
//        if(isJudge && bitmapTowValuedType != ParameterUtil.TowValuedType.FLOYD_STEINBERY) {
//            return img;
//        }
//
//        int threshold = 127;
//
//        String convertGreyImgByFloyd = SharedPreferencesUtil.getContentByKey("convertGreyImgByFloyd", context);
//        if(convertGreyImgByFloyd != null) {
//            try {
//                threshold = Integer.valueOf(convertGreyImgByFloyd);
//            }catch (Exception e){
//                SharedPreferencesUtil.setContentByKey("convertGreyImgByFloyd",String.valueOf(threshold),context);
//                threshold = 128;
//            }
//        }
//
//        int width = img.getWidth();//获取位图的宽  
//        int height = img.getHeight();//获取位图的高  
//
//        int[] pixels = new int[width * height]; //通过位图的大小创建像素点数组  
//
//        img.getPixels(pixels, 0, width, 0, 0, width, height);
//        int[] gray = new int[height * width];
//        for (int i = 0; i < height; i++) {
//            for (int j = 0; j < width; j++) {
//                int grey = pixels[width * i + j];
//                int red = ((grey & 0x00FF0000) >> 16);
//                int green = ((grey & 0x0000FF00) >> 8);
//                int blue = (grey & 0x000000FF);
//                gray[width * i + j] = (int) (0.29900 * red + 0.58700 * green + 0.11400 * blue); // 灰度转化公式;
//            }
//        }
//
//        int e = 0;
//        for (int i = 0; i < height; i++) {
//            for (int j = 0; j < width; j++) {
//                int g = gray[width * i + j];
//                if (g > threshold) {
//                    pixels[width * i + j] = 0xffffffff;
//                    e = g - 255;
//                } else {
//                    pixels[width * i + j] = 0xff000000;
//                    e = g;
//                }
//
////                int a = (e * 7) / 16;
////                int b = (e * 1) / 16;
////                int c = (e * 5) / 16;
////                int d = (e * 3) / 16;
//
////                if(i != height - 1 && j != 0 && j != width - 1){
////                    pixels[width * i + j + 1] += a;
////                    pixels[width * (i + 1) + j + 1] += b;
////                    pixels[width * (i + 1) + j] += c;
////                    pixels[width * (i + 1) + j - 1] += d;
////                }
//
//                if (j<width-1&&i<height-1) {//可 处理 右 下
//                    //右边像素处理
//                    gray[width*i+j+1]+=3*e/8;
//                    judgePoint(gray,i,j+1,width);
//                    //下
//                    gray[width*(i+1)+j]+=3*e/8;
//                    judgePoint(gray,i + 1,j,width);
//                    //右下
//                    gray[width*(i+1)+j+1]+=e/4;
//                    judgePoint(gray,i + 1,j + 1,width);
//                }else if (j==width-1&&i<height-1) {//靠右或靠下边的像素的情况
//                    //下方像素处理
//                    gray[width*(i+1)+j]+=3*e/8;
//                    judgePoint(gray,i + 1,j,width);
//                }else if (j<width-1&&i==height-1) {
//                    //右边像素处理
//                    gray[width*(i)+j+1]+=3*e/8;
//                    judgePoint(gray,i,j + 1,width);
//                }
//
////                //处理四个角
////                if (i == 0 && j == 0) {//左上角 可以处理 右 右下 下
////                    //右
////                    gray[width * i + j + 1] += e * 7 / 16;
////                    judgePoint(gray,i,j + 1,width);
////
////                    //下
////                    gray[width * (i + 1) + j] += e * 5 / 16;
////                    judgePoint(gray,i + 1,j,width);
////
////                    //右下
////                    gray[width * (i + 1) + j + 1] += e / 16;
////                    judgePoint(gray,i + 1,j + 1,width);
////                } else if (i == height - 1 && j == 0) {//左下角 只能处理 右
////                    gray[width * i + j + 1] += e * 7 / 16;
////                    judgePoint(gray,i,j + 1,width);
////                } else if (i == 0 && j == width - 1) {//右上角 处理 下 左下
////                    //下
////                    gray[width * (i + 1) + j] += e * 5 / 16;
////                    judgePoint(gray,i + 1,j,width);
////                    //左下
////                    gray[width * (i + 1) + j - 1] += e * 3 / 16;
////                    judgePoint(gray,i + 1,j - 1,width);
////                } else if (i == height - 1 && j == width - 1) {//右下角 没有可以处理的点
////
////                } else if (i == 0) {//如果靠在上边的点 可以处理全部
////                    //右
////                    gray[width * i + j + 1] += e * 7 / 16;
////                    judgePoint(gray,i,j + 1,width);
////                    //下
////                    gray[width * (i + 1) + j] += e * 5 / 16;
////                    judgePoint(gray,i + 1,j,width);
////                    //右下
////                    gray[width * (i + 1) + j + 1] += e / 16;
////                    judgePoint(gray,i + 1,j + 1,width);
////                    //左下
////                    gray[width * (i + 1) + j - 1] += e * 3 / 16;
////                    judgePoint(gray,i + 1,j - 1,width);
////                } else if (i == height - 1) {//如果靠在下边的点 只能处理右
////                    gray[width * i + j + 1] += e * 7 / 16;
////                    judgePoint(gray,i,j + 1,width);
////                } else if (j == 0) {//如果靠在左边的点 处理 右 下 右下
////                    //右
////                    gray[width * i + j + 1] += e * 7 / 16;
////                    judgePoint(gray,i,j + 1,width);
////                    //下
////                    gray[width * (i + 1) + j] += e * 5 / 16;
////                    judgePoint(gray,i + 1,j,width);
////                    //右下
////                    gray[width * (i + 1) + j + 1] += e / 16;
////                    judgePoint(gray,i + 1,j + 1,width);
////                } else if (j == width - 1) {//如果靠在右边的点 处理 下 左下
////                    //下
////                    gray[width * (i + 1) + j] += e * 5 / 16;
////                    judgePoint(gray,i + 1,j,width);
////                    //左下
////                    gray[width * (i + 1) + j - 1] += e * 3 / 16;
////                    judgePoint(gray,i + 1,j - 1,width);
////                } else {//剩余的点，处理全部
////                    //右
////                    gray[width * i + j + 1] += e * 7 / 16;
////                    judgePoint(gray,i,j + 1,width);
////                    //下
////                    gray[width * (i + 1) + j] += e * 5 / 16;
////                    judgePoint(gray,i + 1,j,width);
////                    //右下
////                    gray[width * (i + 1) + j + 1] += e / 16;
////                    judgePoint(gray,i + 1,j + 1,width);
////                    //左下
////                    gray[width * (i + 1) + j - 1] += e * 3 / 16;
////                    judgePoint(gray,i + 1,j - 1,width);
////                }
//            }
//        }
//        Bitmap mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
//        mBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
//        return mBitmap;
//    }

    private static boolean isContinue = true;

    /**
     * 处理半色调图片
     *
     * @param img
     * @return
     */
    public static Bitmap convertGreyImgByFloyd(Bitmap img, Context context, boolean isJudge) {

        if(!ImageUtil.isContinue) {
            return convertGreyImgAtkinson(img);
        }
//        int bitmapTowValuedType = ParameterUtil.getBitmapTowValuedType(context);
//        if (bitmapTowValuedType != ParameterUtil.TowValuedType.FLOYD_STEINBERY) {
//            return img;
//        }

        int threshold = 128;

        String convertGreyImgByFloyd = SharedPreferencesUtil.getContentByKey("convertGreyImgByFloyd", context);
        if (convertGreyImgByFloyd != null) {
            try {
                threshold = Integer.valueOf(convertGreyImgByFloyd);
            } catch (Exception e) {
                SharedPreferencesUtil.setContentByKey("convertGreyImgByFloyd", String.valueOf(threshold), context);
                threshold = 128;
            }
        }

        int width = img.getWidth();//获取位图的宽  
        int height = img.getHeight();//获取位图的高  

        int[] pixels = new int[width * height]; //通过位图的大小创建像素点数组  

        img.getPixels(pixels, 0, width, 0, 0, width, height);
        int[] gray = new int[height * width];
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int grey = pixels[width * i + j];
                int red = ((grey & 0x00FF0000) >> 16);
                int green = ((grey & 0x0000FF00) >> 8);
                int blue = (grey & 0x000000FF);
                gray[width * i + j] = (int) (0.29900 * red + 0.58700 * green + 0.11400 * blue); // 灰度转化公式;
            }
        }

        int e = 0;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int g = gray[width * i + j];
                if (g > threshold) {
                    pixels[width * i + j] = 0xffffffff;
                    e = g - 255;
                } else {
                    pixels[width * i + j] = 0xff000000;
                    e = g - 0;
                }

                if (j < width - 1 && i < height - 1) {
                    //右边像素处理
                    gray[width * i + j + 1] += 3 * e / 8;
                    //下
                    gray[width * (i + 1) + j] += 3 * e / 8;
                    //右下
                    gray[width * (i + 1) + j + 1] += e / 4;
                } else if (j == width - 1 && i < height - 1) {//靠右或靠下边的像素的情况
                    //下方像素处理
                    gray[width * (i + 1) + j] += 3 * e / 8;
                } else if (j < width - 1 && i == height - 1) {
                    //右边像素处理
                    gray[width * (i) + j + 1] += 3 * e / 8;
                }

//                //处理四个角
//                if (i == 0 && j == 0) {//左上角 可以处理 右 右下 下
//                    //右
//                    gray[width * i + j + 1] += e * 7 / 16;
//                    //下
//                    gray[width * (i + 1) + j] += e * 5 / 16;
//                    //右下
//                    gray[width * (i + 1) + j + 1] += e * 1 / 16;
//                } else if (i == height - 1 && j == 0) {//左下角 只能处理 右
//                    gray[width * i + j + 1] += e * 7 / 16;
//                } else if (i == 0 && j == width - 1) {//右上角 处理 下 左下
//                    //下
//                    gray[width * (i + 1) + j] += e * 5 / 16;
//                    //左下
//                    gray[width * (i + 1) + j - 1] += 3 / 16 * e;
//                } else if (i == height - 1 && j == width - 1) {//右下角 没有可以处理的点
//
//                } else if (i == 0) {//如果靠在上边的点 可以处理全部
//                    //右
//                    gray[width * i + j + 1] += e * 7 / 16;
//                    //下
//                    gray[width * (i + 1) + j] += e * 5 / 16;
//                    //右下
//                    gray[width * (i + 1) + j + 1] += e * 1 / 16;
//                    //左下
//                    gray[width * (i + 1) + j - 1] += 3 / 16 * e;
//                } else if (i == height - 1) {//如果靠在下边的点 只能处理右
//                    gray[width * i + j + 1] += e * 7 / 16;
//                } else if (j == 0) {//如果靠在左边的点 处理 右 下 右下
//                    //右
//                    gray[width * i + j + 1] += e * 7 / 16;
//                    //下
//                    gray[width * (i + 1) + j] += e * 5 / 16;
//                    //右下
//                    gray[width * (i + 1) + j + 1] += e * 1 / 16;
//                } else if (j == width - 1) {//如果靠在右边的点 处理 下 左下
//                    //下
//                    gray[width * (i + 1) + j] += e * 5 / 16;
//                    //左下
//                    gray[width * (i + 1) + j - 1] += 3 / 16 * e;
//                } else {//剩余的点，处理全部
//                    //右
//                    gray[width * i + j + 1] += e * 7 / 16;
//                    //下
//                    gray[width * (i + 1) + j] += e * 5 / 16;
//                    //右下
//                    gray[width * (i + 1) + j + 1] += e * 1 / 16;
//                    //左下
//                    gray[width * (i + 1) + j - 1] += 3 / 16 * e;
//                }
            }
        }
        Bitmap mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        mBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        return mBitmap;
    }

//        return convertGreyImgAtkinson(img);

    /**
     * 判断一个点是否 超过了 255 或者 低于0 如果超过了或低于 则置为255 或者 0
     */
    public static void judgePoint(int[] pixels, int i, int j, int width) {
        int point = pixels[width * i + j];
        if (point > 255) {
            pixels[width * i + j] = 255;
        } else if (point < 0) {
            pixels[width * i + j] = 0;
        }
    }

    /**
     * 图片拷贝
     *
     * @param bitmap
     * @return
     */
    public static Bitmap bitmapCopy(Bitmap bitmap) {
        int width = bitmap.getWidth();//获取位图的宽  
        int height = bitmap.getHeight();//获取位图的高  

        int[] pixels = new int[width * height]; //通过位图的大小创建像素点数组  

        bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
        int[] gray = new int[height * width];
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int grey = pixels[width * i + j];
                gray[width * i + j] = grey; // 灰度转化公式;
            }
        }
        Bitmap mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        mBitmap.setPixels(gray, 0, width, 0, 0, width, height);
        return mBitmap;
    }

    public static Bitmap convertGreyImgByFloyd(Bitmap img, Context context) {
        return convertGreyImgByFloyd(img, context, true);
    }

}
